<template>
  <div class="login">
    <el-form ref="loginFormRef" :model="loginForm" :rules="loginRules" class="login-form">
      <h3 class="title">Piece中控平台</h3>
      <el-form-item prop="uname" class="m-b-20">
        <el-input ref="uname" v-model="loginForm.uname" tabindex="1" type="text" auto-complete="off" placeholder="请输入账号">
          <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
        </el-input>
      </el-form-item>
      <el-tooltip v-model="capsTooltip" content="大写锁定已打开" placement="right" manual>
        <el-form-item prop="pword" class="m-b-20">
          <el-input v-model.trim="loginForm.pword" ref="pword"
                    type="password"
                    autocomplete="off"
                    placeholder="请输入密码"
                    tabindex="2"
                    show-password
                    @keyup.native="checkCapslock"
                    @blur="capsTooltip = false">
            <svg-icon slot="prefix" icon-class="lock" class="el-input__icon input-icon" />
          </el-input>
        </el-form-item>
      </el-tooltip>
      <el-form-item v-if="showValid" prop="captcha" class="m-b-20">
        <el-input
          v-model="loginForm.captcha"
          auto-complete="off"
          placeholder="请输入验证码"
          style="width: 50%"
          @keyup.enter.native="handleLogin"
        >
          <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
        </el-input>
        <div class="login-code">
          <img ref="verify_code" style="width: 130px;height: 35px;cursor: pointer;" alt="点击切换" :src="verifyUrl" @click="getVerifyCode">
        </div>
      </el-form-item>
      <el-form-item style="text-align: center;margin-bottom: 30px;">
        <el-button
          :loading="loading"
          v-waves
          class="login-btn m-r-5 fl"
          size="medium"
          type="primary"
          @click.native.prevent="handleLogin"
        >
          <span v-if="!loading">登 录</span>
          <span v-else>登 录 中...</span>
        </el-button>
        <el-dropdown @command="handleCommand" class="fr">
          <el-link size="medium" type="primary" icon="el-icon-setting" :underline="false" />
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item command="a"> 自动 </el-dropdown-item>
            <el-dropdown-item command="b">局域网</el-dropdown-item>
            <el-dropdown-item command="c">互联网</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
        <div class="help-block el-col-10 fr">
          没有账号？
          <router-link to="/register" class="help-block"><el-link type="primary">注 册</el-link></router-link>
        </div>
      </el-form-item>

      <el-divider v-if="oauthLink.length > 0" class="help-block"><span class="blue mt-5">链接登陆</span></el-divider>
      <el-form-item v-if="oauthLink.length > 0" style="width: 100%">
        <div class="oauth-login">
          <div class="oauth-login-item" :class="{'m-r-20':index!==oauthLink.length - 1}" v-for="(link, index) in oauthLink" :key="link.type" @click="getSocialLink(link)">
            <img :src="link.image" height="25px" width="25px" :title="link.title" >
          </div>
        </div>
      </el-form-item>
    </el-form>
    <!--  底部  -->
    <div class="el-login-footer">
      <span>Copyright © {{ copyright }} All Rights Reserved.</span>
      <span class="fr m-r-10"><el-input v-model="cloudAddress" auto-complete="off" placeholder="请输云地址" style="width: 180px;" @keyup.enter.native="handleCloudAddress"/></span>
    </div>

    <el-dialog v-el-drag-dialog :visible.sync="openOauthDialog" width="400px" top="8vh" custom-class="oauth-dialog" :append-to-body="false" :before-close="closeSocket">
      <i-frame :src="oauthRedirect" id="oauthRedirectFrame"></i-frame>
    </el-dialog>
  </div>
</template>

<script>
import { getSocialData, getSocialLink, checkValidateCode } from '@/api/system/user'
import { getUUID } from '@/utils/index'
import SockJS from 'sockjs-client'
import Stomp from 'stompjs'
import iFrame from '@/components/IFrameView/index'
// import Verify from 'vue2-verify'

export default {
  name: 'Login',
  directives: {
    focus: {
      inserted(el) {
        el.querySelector('input').focus()
      }
    }
  },
  components: { iFrame },
  data() {
    return {
      stompClient: undefined,
      stompSession: undefined,
      loginForm: {
        uname: '',
        pword: '',
        captcha: '',
        validate_code_session: '',
        grant_type: 'username_code'
      },
      loading: false,
      capsTooltip: false,
      redirect: undefined,
      verifyUrl: '',
      oauthLink: [],
      copyright: '',
      openOauthDialog: false,
      oauthRedirect: '',
      cloudAddress: ''
    }
  },
  computed: {
    showSettings: {
      get() {
        return this.$store.state.settings.showSettings
      },
      set(val) {
        this.$store.dispatch('settings/changeSetting', {
          key: 'showSettings',
          value: true
        })
      }
    },
    showValid: {
      get() {
        return this.handleValid()
      }
    },
    loginRules: {
      get() {
        const validCaptcha = this.handleValid()
        return {
          uname: [
            {required: true, trigger: 'blur', message: '请输入登录账号'}
          ],
          pword: [
            {required: true, trigger: 'blur', message: '请输入密码'}
          ],
          captcha: [{required: validCaptcha, trigger: 'change', message: '请输入验证码'}]
        }
      }
    }
  },
  watch: {
    $route: {
      handler: function(route) {
        this.redirect = route.query && route.query.redirect
      },
      immediate: true
    }
  },
  created() {
    this.$nextTick(() => {
      document.body.style.overflow = 'hidden'
      window.addEventListener('beforeunload', e => this.closeSocket(e))
    })
  },
  mounted() {
    this.loginForm.validate_code_session = getUUID()
    this.getCopyright()
    this.getSocialData()
    this.showValiad = this.handleValid()
    if (this.loginForm.uname === '') {
      this.$refs.uname.focus()
    } else if (this.loginForm.pword === '') {
      this.$refs.pword.focus()
    }

    if (this.showValiad) {
      this.getVerifyCode()
      const this_ = this
      setTimeout(() => {
        this_.$refs.verify_code.click()
      }, 1000)
    }
  },
  methods: {
    handleCloseSetting() {
      this.$store.dispatch('settings/changeSetting', {
        key: 'showSettings',
        value: false
      })
    },
    async handleValid() {
      let show = false
      await checkValidateCode().then(response => {
        show = response.param
      }).catch(() => {
        show = true
      })

      return show
    },
    checkCapslock(e) {
      const { key } = e
      this.capsTooltip = key && key.length === 1 && (key >= 'A' && key <= 'Z')
    },
    getCopyright() {
      this.$copyright().then(response => {
        this.copyright = response.param
      }).catch(e => {})
    },
    getVerifyCode() {
      if (this.showValiad) {
        this.verifyUrl = this.$store.state.app.server_api + `${process.env.VUE_APP_MODULE_ADMIN_API}/authentication/code/captcha?validate_code_session=` +
          this.loginForm.validate_code_session + '&r=' + Math.random()
      }
    },
    getSocialData() {
      getSocialData().then(response => {
        this.oauthLink = response.param
      }).catch(e => {})
    },
    getSocialLink(link) {
      this.loading = true
      getSocialLink(link.type, {
        'session': this.stompSession,
        'redirectUri': this.$store.state.app.server_api + `${process.env.VUE_APP_MODULE_ADMIN_API}/oauth/social/callback/${link.type}`
      }).then(response => {
        this.stompSession = response.param.session
        this.openSocket()
        this.oauthRedirect = response.param.url
        this.openOauthDialog = true
      }).catch(() => {})
    },
    openSocket() {
      if (this.stompClient === undefined) {
        const socket = new SockJS(this.$store.state.app.server_api + `${process.env.VUE_APP_MODULE_ADMIN_API}/stomp`)
        // 使用STMOP子协议的WebSocket客户端
        this.stompClient = Stomp.over(socket)
        // 连接WebSocket服务端
        this.stompClient.connect({}, (frame) => {
          this.stompClient.subscribe('/user/' + this.stompSession + '/queue/oauth/callback', (event) => {
            this.stompSession = undefined
            const social = JSON.parse(event.body)
            if (social.bind) {
              this.$store.dispatch('user/quickLogin', social.accessToken)
              this.$router.push({ path: this.redirect || '/' })
            } else {
              this.$router.push({ path: '/register', query: {
                  redirect: this.redirect || '/',
                  params: JSON.stringify(social)
              }})
            }
          })
        }, e => {})
      }
    },
    closeSocket() {
      this.stompSession = undefined
      if (this.stompClient !== undefined) {
        this.stompClient.disconnect()
        this.stompClient = undefined
      }
    },
    handleLogin() {
      this.$refs.loginFormRef.validate(valid => {
        if (valid) {
          this.loading = true
          this.$store.dispatch('user/login', this.loginForm).then(() => {
            this.$router.push({ path: this.redirect || '/' })
            this.loading = false
          }).catch(() => {
            this.loading = false
            this.getVerifyCode()
          })
        } else {
          return false
        }
      })
    },
    handleCommand(command) {
      switch (command) {
        case 'a':
          this.$store.dispatch('app/setServerApi', { serverApi: window.location.protocol + '//' + window.location.host + ':' + window.location.port + process.env.VUE_APP_BASE_API})
          break
        case 'b':
          this.$store.dispatch('app/setServerApi', { serverApi: process.env.VUE_APP_URL_PREFIX })
          break
        case 'c':
          this.$store.dispatch('app/setServerApi', { serverApi: 'http://piece-aliyun.com' + process.env.VUE_APP_BASE_API })
          break
      }
      this.$message({
        type: 'success',
        message: '成功切换服务器地址'
      })
      this.getVerifyCode()
    },
    handleCloudAddress() {
      if (this.cloudAddress.startsWith('http')) {
        this.$store.dispatch('app/setServerApi', { serverApi: this.cloudAddress + process.env.VUE_APP_BASE_API })
      }
      this.$store.dispatch('app/setServerApi', { serverApi: 'http://' + this.cloudAddress + process.env.VUE_APP_BASE_API })
      this.$message({
        type: 'success',
        message: '成功切换服务器地址'
      })
      this.getVerifyCode()
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss">
  .login {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
    background-image: url("~@/assets/images/background.jpg");
    background-size: cover;

    ::v-deep .el-dialog.oauth-dialog {
      height: auto;
      max-height: 80vh;
      overflow-y: auto;
    }
    ::v-deep .el-dialog__body {
      max-height: 70vh!important;
    }
  }
  .title {
    margin: 30px auto 30px auto;
    text-align: center;
    color: #707070;
    font-size: 26px;
    font-weight: 400;
    color: rgba(14, 18, 26, 1);
  }

  .login-form {
    border-radius: 6px;
    background-color: rgba(255,255,255,0.8);
    width: 400px;
    padding: 25px 60px;
    .el-input {
      height: 38px;
      input {
        height: 38px;
      }
    }
    .input-icon {
      height: 39px;
      width: 14px;
      margin-left: 2px;
    }
  }
  .login-tip {
    font-size: 13px;
    text-align: center;
    color: #bfbfbf;
  }
  .svg-container {
    position: absolute;
    left: 6px;
    z-index: 999;
    font-size: 16px;
    color: #C0C4CC;
    cursor: pointer;
    user-select: none;
  }
  .svg-container + .el-input {
    input {
      padding-left: 30px;
    }
  }
  .show-password {
    position: absolute;
    top: 7px;
    right: 25px;
    font-size: 16px;
    color:#C0C4CC;
    cursor: pointer;
    user-select: none;
  }
  .login-code {
    height: 38px;
    float: right;
    img {
      cursor: pointer;
      vertical-align: middle;
    }
  }
  .el-login-footer {
    height: 40px;
    line-height: 40px;
    position: fixed;
    bottom: 0;
    width: 100%;
    text-align: center;
    background-color: rgba(255,255,255,0.4);
    font-family: Arial;
    font-size: 12px;
    letter-spacing: 1px;
  }
  .oauth-login {
    display: flex;
    align-items: center;
    justify-content: center;
    cursor:pointer;
    margin-top: 15px;
  }
  .oauth-login-item {
    display: flex;
    align-items: center;
    margin-right: 10px;
  }
  .oauth-login-item img {
    height: 25px;
    width: 25px;
  }
  .oauth-login-item span:hover {
    text-decoration: underline red;
    color: red;
  }
</style>
